#include <stdio.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <linux/fb.h>
#include <linux/input.h>
#include <sys/time.h>
#include "taiji.h"
#include "slide.h"
#include "sheet.h"  // 通过sheet.h引用sheet
#include "local.h"
#include "network.h"

// 信号宏定义
#define RESTART_REQUEST 4     // 重玩请求
#define RESTART_AGREE 5       // 同意重玩
#define RESTART_REFUSE 6      // 拒绝重玩  
#define RESTART_DENIED 7      // 重玩被拒绝

extern int gameEnded;  // 声明gameEnded为外部定义的变量

int is_my_turn = 1;       // 回合标志，1表示当前是本地回合
int my_color = 1;         // 1表示黑棋，2表示白棋
int opponent_color = 2;   // 对手颜色
int connected_clients = 0; // 记录已连接的客户端数量
int client_id = 0;         // 客户端编号，全局变量
int show_turn_indicator = 1; // 是否显示回合指示器

// 断线重连相关变量
int game_in_progress = 0;   // 是否有进行中的游戏
int saved_client_id = 0;    // 保存的客户端ID
int saved_my_color = 0;     // 保存的己方颜色
int saved_opponent_color = 0; // 保存的对手颜色
int saved_is_my_turn = 0;   // 保存的回合状态
int saved_sheet[16][16] = {0}; // 保存的棋盘状态

// 重玩相关状态变量
int waiting_for_restart_response = 0; // 等待对方对重玩请求的响应
int show_restart_request = 0;         // 显示重玩请求对话框

// 添加计时器相关变量
struct timeval restart_denied_time;  // 记录显示拒绝提示的时间
int show_restart_denied = 0;         // 标记是否显示拒绝提示

// 添加一个绘制矩形背景的辅助函数（用于清除特定区域）
void draw_background_rect(int x, int y, int width, int height, int color) {
    for (int i = y; i < y + height && i < lcd_info.yres; i++) {
        for (int j = x; j < x + width && j < lcd_info.xres; j++) {
            draw_pixel(j, i, color);
        }
    }
}

// 保存游戏状态
void save_game_state() {
    game_in_progress = 1;
    saved_client_id = client_id;
    saved_my_color = my_color;
    saved_opponent_color = opponent_color;
    // 保存当前回合状态
    saved_is_my_turn = is_my_turn;
    
    // 保存棋盘状态
    for (int i = 0; i < 16; i++) {
        for (int j = 0; j < 16; j++) {
            saved_sheet[i][j] = sheet[i][j];
        }
    }
    printf("游戏状态已保存 - 客户端ID:%d, 我的颜色:%d, 我的回合:%d\n", 
           saved_client_id, saved_my_color, saved_is_my_turn);
}

// 加载游戏状态
void load_game_state() {
    if (game_in_progress) {
        client_id = saved_client_id;
        my_color = saved_my_color;
        opponent_color = saved_opponent_color;
        is_my_turn = saved_is_my_turn;
        
        // 恢复棋盘状态
        for (int i = 0; i < 16; i++) {
            for (int j = 0; j < 16; j++) {
                sheet[i][j] = saved_sheet[i][j];
            }
        }
        printf("游戏状态已恢复 - 客户端ID:%d, 我的颜色:%d, 我的回合:%d\n", 
               client_id, my_color, is_my_turn);
    }
}

// 尝试重连到服务器
int try_reconnect(char *ip, int port) {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return -1;
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);
    
    int ret = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    if (ret < 0) {
        perror("connect");
        close(sockfd);
        return -1;
    }
    
    printf("重连服务器成功\n");
    return sockfd;
}

// 继续游戏的主循环
void continue_game(int sockfd) {
    // 重绘游戏界面
    draw_background(0xffffff);
    draw_picture(0,0,"./picture/checkerboard.bmp");
    draw_picture(500,0,"./picture/what.bmp");
    draw_picture(700,380,"./picture/huitui.bmp");
    draw_picture(480,400,"./picture/gameagain.bmp");
    draw_picture(720,0,"./picture/surrender.bmp");
    checkerboard();
    
    // 绘制所有棋子
    for (int i = 0; i < 16; i++) {
        for (int j = 0; j < 16; j++) {
            if (sheet[i][j] == 1) {  // 黑棋
                draw_round1(i*30 + 10, j*30 + 10, 10, 0x000000);
                draw_round2(i*30 + 10, j*30 + 10, 10, 0x000000);
            } else if (sheet[i][j] == 2) {  // 白棋
                draw_round1(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
                draw_round2(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
            }
        }
    }
    
    // 绘制回合提示
    draw_turn_indicator();

    fd_set readfds;
    struct timeval tv;
    
    // 初始化触摸屏文件
    open_file();
    int touch_fd = fileno(abs_screen);
    
    // 重置游戏状态 - 确保重连时不显示胜利状态
    gameEnded = 0;
    show_turn_indicator = 1;
    waiting_for_restart_response = 0;
    show_restart_request = 0;
    show_restart_denied = 0;
    
    // 进入游戏主循环
    game_main_loop(sockfd, touch_fd);
}

// 游戏主循环
void game_main_loop(int sockfd, int touch_fd) {
    fd_set readfds;
    struct timeval tv;
    int ret;
    
    while (1) {
        // 检查拒绝提示是否超时（1秒）
        if (show_restart_denied) {
            struct timeval now;
            gettimeofday(&now, NULL);
            
            long elapsed_seconds = now.tv_sec - restart_denied_time.tv_sec;
            long elapsed_microseconds = now.tv_usec - restart_denied_time.tv_usec;
            long total_elapsed_ms = elapsed_seconds * 1000 + elapsed_microseconds / 1000;
            
            if (total_elapsed_ms >= 1000) {
                show_restart_denied = 0;
                // 使用双缓冲技术重绘界面
                prepare_double_buffer();
                int *temp_lcd_fp = lcd_fp;
                lcd_fp = back_buffer;
                redraw_game_interface();
                lcd_fp = temp_lcd_fp;
                swap_buffer();
            }
        }
        
        // 原有的select监听代码
        FD_ZERO(&readfds);
        FD_SET(sockfd, &readfds);
        FD_SET(touch_fd, &readfds);  // 监听触摸屏文件
        FD_SET(0, &readfds);  // 标准输入，用于调试
        
        // 计算最大文件描述符
        int max_fd = sockfd > touch_fd ? sockfd : touch_fd;
        
        // 设置更小的超时，提高响应速度
        tv.tv_sec = 0;
        tv.tv_usec = 50000;  // 50ms，减少延迟
        
        ret = select(max_fd + 1, &readfds, NULL, NULL, &tv);
        if (ret < 0) {
            perror("select");
            continue;
        }

        // 处理触摸屏事件
        if (FD_ISSET(touch_fd, &readfds)) {
            int dir_result = direction();
            if (dir_result == 0) {  // 检测到有效点击
                // 首先处理拒绝提示期间的触摸
                if (show_restart_denied) {
                    // 处理返回和重玩按钮
                    if (end_x < 800 && end_y > 380 && end_x > 700 && end_y < 480) {
                        // 只有在游戏进行中时才保存状态
                        if (!gameEnded) {
                            save_game_state(); // 保存游戏状态
                        } else {
                            game_in_progress = 0;
                            printf("游戏已结束，清除保存状态\n");
                        }
                        close(sockfd);
                        close_file();
                        chess_again();
                        longjmp(jmpbuffer, 1);
                    }
                   else if (end_x < 560 && end_y > 380 && end_x > 480 && end_y < 480) {
                        int restart_flag = 8; // 使用8而不是1，避免与黑胜标志冲突
                        send(sockfd, &restart_flag, sizeof(restart_flag), 0);
                        waiting_for_restart_response = 1;
                        show_restart_denied = 0;
                        // 使用双缓冲技术绘制等待响应界面
                        prepare_double_buffer();
                        
                        // 重绘整个游戏界面到缓冲区
                        int *temp_lcd_fp = lcd_fp;
                        lcd_fp = back_buffer;
                        redraw_game_interface();
                        lcd_fp = temp_lcd_fp;
                        
                        // 在缓冲区绘制等待响应图片
                        draw_picture_buffer(200, 190, "./picture/waiting_response.bmp");
                        
                        // 一次性交换缓冲区，避免闪烁
                        swap_buffer();
                    }
                }
                
                // 检查是否点击返回按钮（无论游戏是否结束都应响应）
                if (end_x < 800 && end_y > 380 && end_x > 700 && end_y < 480) {
                    // 只有在游戏进行中时才保存状态，允许断线重连时恢复
                    if (!gameEnded) {
                        save_game_state(); // 保存游戏状态
                        printf("游戏进行中，已保存游戏状态\n");
                    } else {
                        // 游戏已结束，清除保存的状态
                        game_in_progress = 0;
                        printf("游戏已结束，清除保存状态\n");
                    }
                    close(sockfd); // 关闭网络连接
                    close_file();
                    chess_again();
                    longjmp(jmpbuffer, 1);  // 返回主界面
                }
                // 处理重玩按钮（核心修改：无论游戏是否结束，都发送请求）
                else if (end_x < 560 && end_y > 380 && end_x > 480 && end_y < 480) {
                    // 避免重复发送请求
                    if (waiting_for_restart_response) {
                        continue;
                    }
                    // 发送重玩请求（和对局中逻辑一致）
                    int restart_flag = 8; // 使用8而不是1，避免与黑胜标志冲突
                    send(sockfd, &restart_flag, sizeof(restart_flag), 0);
                    waiting_for_restart_response = 1;  // 标记等待响应
                    // 显示等待提示（覆盖结束界面）
                    // 使用双缓冲技术绘制等待响应界面
                    prepare_double_buffer();
                    
                    // 重绘整个游戏界面到缓冲区
                    int *temp_lcd_fp = lcd_fp;
                    lcd_fp = back_buffer;
                    redraw_game_interface();
                    lcd_fp = temp_lcd_fp;
                    
                    // 在缓冲区绘制等待响应图片
                    draw_picture_buffer(200, 190, "./picture/waiting_response.bmp");
                    
                    // 一次性交换缓冲区，避免闪烁
                    swap_buffer();
                    // 关键：不立即重置gameEnded，保持结束状态直到对方同意
                }
                
                // 首先处理重玩请求对话框
                if (show_restart_request) {
                    // 同意按钮区域：(250,280) 到 (350,310)
                    if (end_x >= 250 && end_x <= 350 && end_y >= 280 && end_y <= 310) {
                        int agree_response = RESTART_AGREE;
                            send(sockfd, &agree_response, sizeof(agree_response), 0);
                            waiting_for_restart_response = 0; // 清除等待标记
                            show_restart_request = 0;
                            
                            // 使用双缓冲技术重绘界面
                            prepare_double_buffer();
                            int *temp_lcd_fp = lcd_fp;
                            lcd_fp = back_buffer;
                            redraw_game_interface();
                            lcd_fp = temp_lcd_fp;
                            swap_buffer();
                            continue;
                    }
                    // 拒绝按钮区域：(450,280) 到 (550,310)
                    else if (end_x >= 450 && end_x <= 550 && end_y >= 280 && end_y <= 310) {
                        int refuse_response = RESTART_REFUSE;
                            send(sockfd, &refuse_response, sizeof(refuse_response), 0);
                            waiting_for_restart_response = 0; // 清除等待标记
                            show_restart_request = 0;
                            
                            // 使用双缓冲技术重绘界面
                            prepare_double_buffer();
                            int *temp_lcd_fp = lcd_fp;
                            lcd_fp = back_buffer;
                            redraw_game_interface();
                            lcd_fp = temp_lcd_fp;
                            swap_buffer();
                            continue;
                    }
                }

                // 游戏未结束时处理落子和投降
                if (!gameEnded) {
                    // 添加调试信息
                    printf("调试: my_color=%d, opponent_color=%d\n", my_color, opponent_color);
                    // 检查是否点击投降按钮
                            if (end_x < 800 && end_y > 0 && end_x > 720 && end_y < 80) {
                                // 通知服务器自己投降，发送对手的胜利标志
                                int win_flag = opponent_color; // 投降时，对手颜色即为胜利者
                                send(sockfd, &win_flag, sizeof(win_flag), 0);
                                
                                // 显示对方胜利画面（因为是我方投降）
                                // 首先设置游戏结束状态，防止任何后续的绘制操作
                                gameEnded = 1;
                                show_turn_indicator = 0;
                                
                                // 确保没有遮挡胜利图片的矩形绘制，直接绘制胜利图片
                                if (win_flag == 1) {
                                    draw_picture(650, 100, "./picture/hei.bmp"); // 黑胜
                                } else if (win_flag == 2) {
                                    draw_picture(650, 100, "./picture/bai.bmp"); // 白胜
                                }
                                
                                // 移除不必要的缓冲区刷新，直接绘制到屏幕
                                
                                continue; // 不退出主循环，继续监听重玩/返回
                    }
                    // 检查是否点击what按钮
                    else if (end_x < 580 && end_y > 0 && end_x > 500 && end_y < 80) {
                        // 显示游戏规则或帮助信息
                        draw_background(0xffffff);
                        draw_picture(0,0,"./picture/checkerboard.bmp");
                        draw_picture(500,0,"./picture/what.bmp");
                        draw_picture(700,380,"./picture/huitui.bmp");
                        draw_picture(480,400,"./picture/gameagain.bmp");
                        draw_picture(720,0,"./picture/surrender.bmp");
                        checkerboard();
                        // 重新绘制所有棋子
                        for (int i = 0; i < 16; i++) {
                            for (int j = 0; j < 16; j++) {
                                if (sheet[i][j] == 1) {  // 黑棋
                                    draw_round1(i*30 + 10, j*30 + 10, 10, 0x000000);
                                    draw_round2(i*30 + 10, j*30 + 10, 10, 0x000000);
                                } else if (sheet[i][j] == 2) {  // 白棋
                                    draw_round1(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
                                    draw_round2(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
                                }
                            }
                        }
                    }
                    
                    // 处理落子（仅自己回合且游戏未结束时）
                    if (is_my_turn) {  // 只有自己的回合才处理
                        int touch_processed = 0;
                        for (int i = 10; i < 480; i += 30) {
                            for (int j = 10; j < 480; j += 30) {
                                if (abs(end_x - i) < 15 && abs(end_y - j) < 15) {
                                    int x = i / 30;
                                    int y = j / 30;
                                    
                                    if (x >= 0 && x < 16 && y >= 0 && y < 16 && sheet[x][y] == 0) {
                                        sheet[x][y] = my_color;
                                        // 打印客户端落子的坐标
                                        printf("客户端落子: 坐标(%d,%d)，棋盘位置[行=%d][列=%d]，棋子颜色=%d\n", 
                                               i, j, x, y, my_color);
                                        touch_processed = 1;
                                        break;
                                    }
                                }
                            }
                            if (touch_processed) break;
                        }
                        
                        if (touch_processed) {
                            // 只绘制自己刚下的棋子，而不是整个棋盘
                            // 找出刚才下的棋子位置
                            for (int i = 0; i < 16; i++) {
                                for (int j = 0; j < 16; j++) {
                                    if (sheet[i][j] == my_color) {  // 找到自己的棋子
                                        // 直接绘制棋子
                                        if (my_color == 1) {  // 黑棋
                                            draw_round1(i*30 + 10, j*30 + 10, 10, 0x000000);
                                            draw_round2(i*30 + 10, j*30 + 10, 10, 0x000000);
                                        } else {  // 白棋
                                            draw_round1(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
                                            draw_round2(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
                                        }
                                    }
                                }
                            }
                            
                            // 移除不必要的缓冲区刷新，直接绘制到屏幕
                            
                            // 发送棋盘数据到服务器
                            size_t send_size = sizeof(sheet);
                            ret = send(sockfd, sheet, send_size, 0);
                            if (ret < 0) {
                                perror("send");
                                break;
                            }
                            // 打印发送给服务器的文件大小
                            printf("发送到服务器: 文件大小=%zu字节，实际发送=%d字节\n", send_size, ret);
                            
                            // 先检查是否获胜，再更新回合指示器
                            if ((my_color == 1 && AWin(0) == 5) || (my_color == 2 && BWin(0) == 5)) {
                                // 首先设置游戏结束状态，防止任何后续的绘制操作
                                gameEnded = 1;
                                show_turn_indicator = 0;
                                
                                // 发送明确的胜利标志给服务器
                                int win_flag = my_color; // 1表示黑胜，2表示白胜
                                send(sockfd, &win_flag, sizeof(win_flag), 0);
                                
                                // 确保没有遮挡胜利图片的矩形绘制，直接绘制胜利图片
                                if (win_flag == 1) {
                                    draw_picture(650, 100, "./picture/hei.bmp"); // 黑胜
                                } else if (win_flag == 2) {
                                    draw_picture(650, 100, "./picture/bai.bmp"); // 白胜
                                }
                                
                                // 移除不必要的缓冲区刷新，直接绘制到屏幕
                                
                                // 不break，继续在主循环中处理重玩请求
                            } else {
                                // 只有在没有获胜的情况下才切换回合并更新指示器
                                is_my_turn = 0;  // 切换到对方回合
                                update_turn_indicator(); // 更新回合提示
                            }
                        }
                    }
                }
            }
        }

        // 接收服务器转发的棋盘数据或控制信号
        if (FD_ISSET(sockfd, &readfds)) {
            // 先窥视4字节，判断是否为控制信号，不消耗数据
            int peek_flag = 0;
            ret = recv(sockfd, &peek_flag, sizeof(peek_flag), MSG_PEEK);
            if (ret <= 0) {
                perror("recv");
                close_file();
                break;
            }

            // 控制信号集合：1黑胜、2白胜、3重玩同步、4重玩请求、7重玩被拒、9断线信号、10游戏开始、12重连通知、13回合状态
            if (peek_flag == 1 || peek_flag == 2 || peek_flag == 3 || peek_flag == 4 || peek_flag == 7 || peek_flag == 9 || peek_flag == 10 || peek_flag == 12 || peek_flag == 13) {
                int win_flag = 0;
                // 读取并消费控制信号
                ret = recv(sockfd, &win_flag, sizeof(win_flag), 0);
                if (ret <= 0) {
                    perror("recv");
                    close_file();
                    break;
                }

                if (win_flag == 4) {
                    show_restart_request = 1;
                    waiting_for_restart_response = 0;
                    // 使用双缓冲绘制请求重玩的对话框
                    prepare_double_buffer();
                    int *temp_lcd_fp = lcd_fp;
                    lcd_fp = back_buffer;
                    redraw_game_interface();
                    lcd_fp = temp_lcd_fp;
                    draw_picture_buffer(200, 140, "./picture/restart_request.bmp");
                    swap_buffer();
                    continue;
                } else if (win_flag == 1 || win_flag == 2) {
                    printf("调试: 接收到胜利标志=%d\n", win_flag);
                    gameEnded = 1;
                    show_turn_indicator = 0;
                    if (win_flag == 1) {
                        draw_picture(650, 100, "./picture/hei.bmp");
                    } else {
                        draw_picture(650, 100, "./picture/bai.bmp");
                    }
                    continue;
                } else if (win_flag == 3) {
                    // 重玩同步
                    chess_again();
                    gameEnded = 0;
                    waiting_for_restart_response = 0;
                    show_restart_request = 0;
                    show_restart_denied = 0;
                    show_turn_indicator = 1;
                    is_my_turn = (client_id == 1) ? 1 : 0;
                    game_in_progress = 0; // 清除保存的状态
                    // 仅在重玩刷新页面时使用双缓冲
                    prepare_double_buffer();
                    draw_background_buffer(0xffffff);
                    draw_picture_buffer(0, 0, "./picture/checkerboard.bmp");
                    draw_picture_buffer(500, 0, "./picture/what.bmp");
                    draw_picture_buffer(700, 380, "./picture/huitui.bmp");
                    draw_picture_buffer(480, 400, "./picture/gameagain.bmp");
                    draw_picture_buffer(720, 0, "./picture/surrender.bmp");
                    int *temp_lcd_fp = lcd_fp;
                    lcd_fp = back_buffer;
                    checkerboard();
                    lcd_fp = temp_lcd_fp;
                    if (show_turn_indicator) {
                        temp_lcd_fp = lcd_fp;
                        lcd_fp = back_buffer;
                        draw_turn_indicator();
                        lcd_fp = temp_lcd_fp;
                    }
                    swap_buffer();
                    continue;
                } else if (win_flag == 7) { // 重玩被拒
                    waiting_for_restart_response = 0;
                    show_restart_denied = 1;
                    gettimeofday(&restart_denied_time, NULL);
                    prepare_double_buffer();
                    int *temp_lcd_fp = lcd_fp;
                    lcd_fp = back_buffer;
                    redraw_game_interface();
                    lcd_fp = temp_lcd_fp;
                    draw_picture_buffer(200, 190, "./picture/restart_denied.bmp");
                    swap_buffer();
                    continue;
                } else if (win_flag == 9) { // 对方断线
                    printf("对方已断线，等待重连...\n");
                    // 显示等待重连的提示
                    draw_background(0xffffff);
                    draw_picture(0,0,"./picture/checkerboard.bmp");
                    draw_picture(500,0,"./picture/what.bmp");
                    draw_picture(700,380,"./picture/huitui.bmp");
                    draw_picture(480,400,"./picture/gameagain.bmp");
                    draw_picture(720,0,"./picture/surrender.bmp");
                    checkerboard();
                    
                    // 重新绘制所有棋子
                    for (int i = 0; i < 16; i++) {
                        for (int j = 0; j < 16; j++) {
                            if (sheet[i][j] == 1) {  // 黑棋
                                draw_round1(i*30 + 10, j*30 + 10, 10, 0x000000);
                                draw_round2(i*30 + 10, j*30 + 10, 10, 0x000000);
                            } else if (sheet[i][j] == 2) {  // 白棋
                                draw_round1(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
                                draw_round2(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
                            }
                        }
                    }
                    
                    // 显示等待重连的提示
                    draw_picture(200, 200, "./picture/waiting_response.bmp");
                    
                    // 设置一个超时机制，如果长时间没有重连，清除保存状态
                    struct timeval disconnect_time;
                    gettimeofday(&disconnect_time, NULL);
                    
                    // 等待重连，但允许用户通过点击返回按钮退出
                    int wait_count = 0;
                    while (wait_count < 1000) { // 等待更长时间，但允许用户随时退出
                        usleep(50000); // 等待50ms
                        wait_count++;
                        
                        // 检查触摸屏事件，允许用户点击返回按钮
                        int dir_result = direction();
                        if (dir_result == 0) {  // 检测到有效点击
                            // 检查是否点击返回按钮
                            if (end_x < 800 && end_y > 380 && end_x > 700 && end_y < 480) {
                                // 保存当前游戏状态（如果需要的话）
                                save_game_state();
                                printf("用户选择退出等待，返回主界面\n");
                                close(sockfd);
                                close_file();
                                chess_again();
                                longjmp(jmpbuffer, 1);  // 返回主界面
                            }
                        }
                        
                        // 检查是否有新的连接或信号
                        fd_set temp_readfds;
                        FD_ZERO(&temp_readfds);
                        FD_SET(sockfd, &temp_readfds);
                        struct timeval temp_tv = {0, 10000}; // 10ms超时
                        
                        if (select(sockfd + 1, &temp_readfds, NULL, NULL, &temp_tv) > 0) {
                            // 有数据到达，跳出等待循环
                            break;
                        }
                    }
                    
                    if (wait_count >= 100) {
                        printf("等待重连超时，清除保存状态\n");
                        game_in_progress = 0;
                        close(sockfd);
                        close_file();
                        chess_again();
                        longjmp(jmpbuffer, 1);
                    }
                    
                    continue;
                } else if (win_flag == 10) { // 游戏开始信号
                    printf("对方已重连，游戏继续\n");
                    // 清除等待重连的提示，恢复正常游戏界面
                    redraw_game_interface();
                    continue;
                } else if (win_flag == 12) { // 重连通知信号
                    printf("对方已重连，清除等待状态\n");
                    // 清除等待重连的提示，恢复正常游戏界面
                    redraw_game_interface();
                    continue;
                } else if (win_flag == 13) { // 回合状态信号
                    // 读取回合状态
                    int received_turn = 0;
                    ret = recv(sockfd, &received_turn, sizeof(received_turn), 0);
                    if (ret > 0) {
                        printf("收到回合状态信号，对方回合:%d\n", received_turn);
                        // 更新回合状态
                        is_my_turn = received_turn;
                        // 更新回合指示器
                        update_turn_indicator();
                        printf("回合状态已更新，我的回合:%d\n", is_my_turn);
                    }
                    continue;
                }
            }

            // 非控制信号：按整块读取棋盘
            int temp_board[16][16];
            size_t expected_size = sizeof(temp_board);
            size_t received_total = 0;
            char *p = (char *)temp_board;
            while (received_total < expected_size) {
                ret = recv(sockfd, p + received_total, expected_size - received_total, 0);
                if (ret <= 0) {
                    perror("recv");
                    close_file();
                    break;
                }
                received_total += (size_t)ret;
            }
            if (received_total < expected_size) {
                break;
            }
            printf("收到服务器转发: 文件大小=%zu字节，期望大小=%zu字节\n", received_total, expected_size);

            // 找出对手新下的棋子位置
            int new_x = -1, new_y = -1;
            for (int i = 0; i < 16; i++) {
                for (int j = 0; j < 16; j++) {
                    if (sheet[i][j] == 0 && temp_board[i][j] == opponent_color) {
                        new_x = i;
                        new_y = j;
                        printf("收到棋子: 棋盘位置[行=%d][列=%d]，棋子颜色=%d\n", new_x, new_y, opponent_color);
                        break;
                    }
                }
                if (new_x != -1) break;
            }

            if (new_x != -1 && new_y != -1) {
                sheet[new_x][new_y] = opponent_color;
                if (opponent_color == 1) {
                    draw_round1(new_x*30 + 10, new_y*30 + 10, 10, 0x000000);
                    draw_round2(new_x*30 + 10, new_y*30 + 10, 10, 0x000000);
                } else {
                    draw_round1(new_x*30 + 10, new_y*30 + 10, 10, 0xF5F5F5);
                    draw_round2(new_x*30 + 10, new_y*30 + 10, 10, 0xF5F5F5);
                }
                
                // 接收对方棋子后立即保存游戏状态
                save_game_state();
            }

            is_my_turn = 1;
            update_turn_indicator();
        }
    }
    
    // 关闭套接字和触摸屏文件
    close(sockfd);
    close_file();
    chess_again();
}

// 添加绘制回合指示器的函数
void draw_turn_indicator() {
    // 游戏结束时或不需要显示回合指示器时，不执行任何绘制操作
    if (gameEnded || !show_turn_indicator) return;
    
    // 根据当前回合显示对应的图片
    // 位置：放在原来黑圆白圆指示器的位置(500,140)
    if (is_my_turn) {
        // 己方回合 - 显示inow.bmp
        draw_picture(500, 140, "./picture/inow.bmp");
    } else {
        // 对方回合 - 显示younow.bmp
        draw_picture(500, 140, "./picture/younow.bmp");
    }
}

// 在回合切换时调用这个函数更新提示
void update_turn_indicator() {
    // 游戏结束时或不需要显示回合指示器时，完全不执行任何绘制操作
    // 这是防止胜利图片被白色矩形覆盖的关键保护
    if (gameEnded || !show_turn_indicator) {
        return;
    }
    // 直接绘制新的回合提示，不再清除背景（移除白色矩形绘制）
    draw_turn_indicator();
}

// 添加一个重绘游戏界面的辅助函数（默认直接绘制到屏幕）
 void redraw_game_interface() {
     // 直接绘制到屏幕
     draw_background(0xffffff);
     draw_picture(0,0,"./picture/checkerboard.bmp");
     draw_picture(500,0,"./picture/what.bmp");
     draw_picture(700,380,"./picture/huitui.bmp");
     draw_picture(480,400,"./picture/gameagain.bmp");
     draw_picture(720,0,"./picture/surrender.bmp");
     checkerboard();
     
     // 更新回合指示器显示
     if (show_turn_indicator) {
         draw_turn_indicator();
     }
     
     
     // 重新绘制所有棋子
     for (int i = 0; i < 16; i++) {
         for (int j = 0; j < 16; j++) {
             if (sheet[i][j] == 1) {
                 draw_round1(i*30 + 10, j*30 + 10, 10, 0x000000);
                 draw_round2(i*30 + 10, j*30 + 10, 10, 0x000000);
             } else if (sheet[i][j] == 2) {
                 draw_round1(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
                 draw_round2(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
             }
         }
     }
     
     // 绘制回合提示图片
     draw_turn_indicator();
}

void network_wzq(char *ip, int port) {
    // 检查是否有保存的游戏状态
    if (game_in_progress) {
        printf("检测到未完成的游戏，尝试重连...\n");
        int sockfd = try_reconnect(ip, port);
        if (sockfd > 0) {
            // 重连成功，恢复游戏状态
            load_game_state();
            
            // 重连时重置游戏状态，避免显示胜利画面
            gameEnded = 0;
            show_turn_indicator = 1;
            waiting_for_restart_response = 0;
            show_restart_request = 0;
            show_restart_denied = 0;
            
            // 确保回合状态正确 - 重连后应该轮到退出的一方
            printf("重连后回合状态 - 我的回合:%d, 我的颜色:%d\n", is_my_turn, my_color);
            
            // 先发送重连信号，通知服务器这是重连
            int reconnect_signal = 11; // 重连信号
            int ret = send(sockfd, &reconnect_signal, sizeof(reconnect_signal), 0);
            if (ret < 0) {
                perror("send reconnect signal");
                close(sockfd);
                game_in_progress = 0;
                return;
            }
            printf("已发送重连信号给服务器\n");
            
            // 等待服务器确认重连，并清除可能的旧信号
            usleep(200000); // 等待200ms
            
            // 清除可能存在的旧信号
            fd_set clear_readfds;
            struct timeval clear_tv = {0, 10000}; // 10ms超时
            char clear_buffer[1024];
            int clear_ret;
            
            FD_ZERO(&clear_readfds);
            FD_SET(sockfd, &clear_readfds);
            
            // 尝试清除旧信号
            while (select(sockfd + 1, &clear_readfds, NULL, NULL, &clear_tv) > 0) {
                clear_ret = recv(sockfd, clear_buffer, sizeof(clear_buffer), MSG_DONTWAIT);
                if (clear_ret <= 0) break;
                printf("清除了 %d 字节的旧信号数据\n", clear_ret);
                FD_ZERO(&clear_readfds);
                FD_SET(sockfd, &clear_readfds);
                clear_tv.tv_sec = 0;
                clear_tv.tv_usec = 10000;
            }
            
            // 发送当前棋盘状态给服务器，确保对方能收到最新状态
            size_t send_size = sizeof(sheet);
            ret = send(sockfd, sheet, send_size, 0);
            if (ret < 0) {
                perror("send board state");
                close(sockfd);
                game_in_progress = 0;
                return;
            }
            printf("已发送棋盘状态给服务器，大小=%zu字节\n", send_size);
            
            // 发送回合状态给服务器，确保对方知道正确的回合
            int turn_signal = 13; // 回合状态信号
            ret = send(sockfd, &turn_signal, sizeof(turn_signal), 0);
            if (ret < 0) {
                perror("send turn signal");
                close(sockfd);
                game_in_progress = 0;
                return;
            }
            // 发送回合信息：1表示我的回合，0表示对方回合
            ret = send(sockfd, &is_my_turn, sizeof(is_my_turn), 0);
            if (ret < 0) {
                perror("send turn state");
                close(sockfd);
                game_in_progress = 0;
                return;
            }
            printf("已发送回合状态给服务器，我的回合:%d\n", is_my_turn);
            
            // 继续游戏逻辑
            continue_game(sockfd);
            return;
        } else {
            printf("重连失败，开始新游戏\n");
            game_in_progress = 0; // 清除保存的状态
        }
    }
    
    // 1. 创建套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return;
    }

    // 2. 连接服务器
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);
    
    int ret = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    if (ret < 0) {
        perror("connect");
        close(sockfd);
        return;
    }
    printf("连接服务器成功\n");

    // 初始化棋盘
    chess_again();
    
    // 接收服务器发送的客户端编号，确定棋子颜色
    ret = recv(sockfd, &client_id, sizeof(client_id), 0);
    if (ret > 0) {
        if (client_id == 1) {
            my_color = 1;         // 第一个客户端是黑棋
            opponent_color = 2;   // 对手是白棋
            is_my_turn = 1;       // 黑棋先行
        } else {
            my_color = 2;         // 第二个客户端是白棋
            opponent_color = 1;   // 对手是黑棋
            is_my_turn = 0;       // 白棋后行
        }
    }
    
    //画出棋盘和相关按钮 - 直接绘制到屏幕
    draw_background(0xffffff);
    draw_picture(0,0,"./picture/checkerboard.bmp");
    draw_picture(500,0,"./picture/what.bmp");
    draw_picture(700,380,"./picture/huitui.bmp");
    draw_picture(480,400,"./picture/gameagain.bmp");
    draw_picture(720,0,"./picture/surrender.bmp");
    checkerboard();
    
    // 尝试接收服务器发送的当前棋局状态
    fd_set read_set;
    FD_ZERO(&read_set);
    FD_SET(sockfd, &read_set);
    
    struct timeval timeout;
    timeout.tv_sec = 0;  // 不阻塞，立即返回
    timeout.tv_usec = 500000;  // 500毫秒超时
    
    int select_ret = select(sockfd + 1, &read_set, NULL, NULL, &timeout);
    if (select_ret > 0 && FD_ISSET(sockfd, &read_set)) {
        // 接收棋盘数据
        int board_data[16*16] = {0};
        int ret = recv(sockfd, board_data, sizeof(board_data), 0);
        
        if (ret == sizeof(board_data)) {
            printf("接收到服务器发送的棋局状态，大小：%d\n", ret);
            // 将接收到的数据转换到sheet数组
            for (int idx = 0; idx < 16*16; idx++) {
                int row = idx / 16;
                int col = idx % 16;
                sheet[row][col] = board_data[idx];
            }
            
            // 标记游戏正在进行中
            game_in_progress = 1;
            // 保存接收到的游戏状态
            save_game_state();
        }
    }
    
    // 绘制所有棋子
    for (int i = 0; i < 16; i++) {
        for (int j = 0; j < 16; j++) {
            if (sheet[i][j] == 1) {  // 黑棋
                draw_round1(i*30 + 10, j*30 + 10, 10, 0x000000);
                draw_round2(i*30 + 10, j*30 + 10, 10, 0x000000);
            } else if (sheet[i][j] == 2) {  // 白棋
                draw_round1(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
                draw_round2(i*30 + 10, j*30 + 10, 10, 0xF5F5F5);
            }
        }
    }
    
    // 在游戏开始时立即绘制回合提示图片，确保正确显示inow.bmp或younow.bmp
    draw_turn_indicator();

    fd_set readfds;
    struct timeval tv;
    
    // 初始化触摸屏文件
    open_file();
    int touch_fd = fileno(abs_screen);
    
    // 重置游戏状态，使用全局的gameEnded变量
    gameEnded = 0;
    show_turn_indicator = 1;  // 确保回合指示器显示
    
    // 进入游戏主循环
    game_main_loop(sockfd, touch_fd);
}